package com.ciaojian.core.service;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ciaojian.core.exception.EntityNotFoundException;
import com.ciaojian.core.mapper.UserMemberMapper;
import com.ciaojian.core.model.Member;
import com.ciaojian.core.model.User;
import com.ciaojian.core.model.UserMember;

import java.util.Date;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 用户和会员卡关联表 服务类
 * </p>
 *
 * @author Atlakyn
 * @since 2021-04-07
 */
public abstract class UserMemberService<M extends BaseMapper<T>, T> extends ServiceImpl<UserMemberMapper, UserMember> {


    /**
     * 检查用户是不是会员
     *
     * @param userId 用户的 id
     * @return -1未开过会员 0开过会员但已过期 1有效会员
     */
    public Integer checkUserMember(Integer userId) {
        UserMember userMember = this.lambdaQuery().eq(UserMember::getUserId, userId).one();
        // 如果没数据表示从未开过会员
        if (userMember == null) {
            return -1;
        }
        // 如果到期日在当前日之后,返回 1 表示是会员;0 表示曾经开过会员但已过期
        return userMember.getDueDate().after(new Date()) ? 1 : 0;
    }

    /**
     * 开通会员
     *
     * @param user 开通用户
     * @param days 开通天数
     */
    public boolean openVip(User user, int memberId, int days) {
        return openVip(user.getId(), memberId, days, TimeUnit.DAYS);
    }

    /**
     * 开通会员
     *
     * @param userId   开通用户
     * @param time     有效期时长
     * @param timeUnit 时间单位
     */
    public boolean openVip(int userId, int memberId, long time, TimeUnit timeUnit) {
        // 判断用户是不是会员，若不是,新增 memberOrder 和 userMember
        Integer isUserMember = this.checkUserMember(userId);
        UserMember userMember = new UserMember();
        long days = timeUnit.toDays(time);
        switch (isUserMember) {
            // 当前无效会员
            case 0:
                userMember = this.lambdaQuery().eq(UserMember::getUserId, userId).one();
                userMember.setOrderNo(null);
                userMember.setDueDate(DateUtil.offset(new Date(), DateField.DAY_OF_YEAR, (int) days));
                break;
            // 非会员
            case -1:
                userMember.setUserId(userId);
                userMember.setOrderNo(null);
                userMember.setDueDate(DateUtil.offsetMonth(new Date(), 12));
                userMember.setMemberId(1);
                break;
            // 当前有效会员
            case 1:
                Member member = Optional.ofNullable(new Member().selectById(memberId))
                        .orElseThrow(() -> new EntityNotFoundException(Member.class, "id", memberId));
                // 可叠加会员时长
                if (member.getOverlay()) {
                    // 延迟会员过期时间
                    userMember = this.lambdaQuery().eq(UserMember::getUserId, userId).one();
                    userMember.setDueDate(DateUtil.offset(userMember.getDueDate(), DateField.DAY_OF_YEAR, (int) days));
                }
                break;
            default:
                break;
        }
        return userMember.insertOrUpdate();
    }
}
